/**
 * Copyright (c) 2023, iDearHanYu Co., Ltd.
 *
 * SPDX-License-Identifier: 
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-09-21     chao         first version
 */

#include <lvgl.h>
#include "volumio_music.h"

LV_IMG_DECLARE(img_volumio_music_wave_top);
LV_IMG_DECLARE(img_volumio_music_wave_bottom);
LV_IMG_DECLARE(img_broadcasting);
LV_IMG_DECLARE(img_cloud_music);
LV_IMG_DECLARE(img_playlists);

struct _focus_obj {
    lv_obj_t *obj;
    int index;
};
typedef struct _focus_obj focus_obj_t;
typedef struct _focus_obj defocus_obj_t;

#define TOP_RES 74 //img_volumio_music_wave_top.header.h;
#define BOTTOM_RES 74 //img_volumio_music_wave_bottom.header.h;

static const void *source_img_buff[SOURCE_MAX] = {
    &img_broadcasting,
    &img_cloud_music,
    &img_playlists,
};

static const lv_font_t *source_font_large;
static const lv_font_t *source_font_small;
static lv_obj_t *source_main_cont;
static lv_obj_t *source_label;
static lv_timer_t *source_timer;
static lv_style_t source_focus_style;
static focus_obj_t focus_obj;
static defocus_obj_t defocus_obj;
static bool leave;

/* private functions */
static lv_obj_t *_create_source_cont(lv_obj_t *parent);
static void _create_wave_images(lv_obj_t *parent);
static lv_obj_t *_create_source_name_box(lv_obj_t *parent);
static lv_obj_t *_create_source_img_box(lv_obj_t *parent);
static void _source_timer_cb(lv_timer_t *timer);
static void _anim_y_cb(void *val, int32_t v);
static void _anim_zoom_cb(void *val, int32_t v);
static void _focus_async_cb(void *param);
static void _defocus_async_cb(void *param);
static void _source_event_cb(lv_event_t * e);

lv_obj_t *volumio_music_source_create(void)
{
    source_font_small = &lv_font_montserrat_22;
    source_font_large = &lv_font_montserrat_32;
    
    leave = false;

    lv_style_init(&source_focus_style);
    lv_style_set_border_color(&source_focus_style, lv_color_hex(0xCEEEFF));

    lv_obj_t *cont = _create_source_cont(lv_scr_act());
    _create_wave_images(cont);
    lv_obj_t *label_box = _create_source_name_box(cont);
    lv_obj_t *img_box = _create_source_img_box(cont);
    
    static const lv_coord_t grid_cols[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
    static const lv_coord_t grid_rows[] = {TOP_RES/2, LV_GRID_CONTENT, LV_GRID_CONTENT, BOTTOM_RES/2, LV_GRID_TEMPLATE_LAST};
    lv_obj_set_grid_dsc_array(cont, grid_cols, grid_rows);
    lv_obj_set_style_grid_row_align(cont, LV_GRID_ALIGN_SPACE_BETWEEN, 0);

    lv_obj_set_grid_cell(label_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 1, 1);
    lv_obj_set_grid_cell(img_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 2, 1);
    
    source_timer = lv_timer_create(_source_timer_cb, 10000, NULL);
	
    return source_main_cont;
}

void volumio_music_source_destroy(void)
{
    lv_timer_del(source_timer);
    leave = true;
    lv_obj_del_async(source_main_cont);
}

static lv_obj_t *_create_source_cont(lv_obj_t *parent)
{
    source_main_cont = lv_obj_create(parent);
    lv_obj_remove_style_all(source_main_cont);
    lv_obj_set_size(source_main_cont, lv_pct(100), lv_pct(100));
    lv_obj_set_style_bg_opa(source_main_cont, LV_OPA_100, 0);
    lv_obj_set_style_bg_color(source_main_cont, lv_color_white(), 0);

    return source_main_cont;
}

static void _create_wave_images(lv_obj_t *parent)
{
    lv_obj_t *wave_top = lv_img_create(parent);
    lv_img_set_src(wave_top, &img_volumio_music_wave_top);
    lv_obj_set_width(wave_top, LV_HOR_RES);
    lv_obj_align(wave_top, LV_ALIGN_TOP_MID, 0, 0);
    lv_obj_add_flag(wave_top, LV_OBJ_FLAG_IGNORE_LAYOUT);

    lv_obj_t *wave_bottom = lv_img_create(parent);
    lv_img_set_src(wave_bottom, &img_volumio_music_wave_bottom);
    lv_obj_set_width(wave_bottom, LV_HOR_RES);
    lv_obj_align(wave_bottom, LV_ALIGN_BOTTOM_MID, 0, 0);
    lv_obj_add_flag(wave_bottom, LV_OBJ_FLAG_IGNORE_LAYOUT);
}

static lv_obj_t *_create_source_name_box(lv_obj_t *parent)
{
    lv_obj_t *cont = lv_obj_create(parent);
    lv_obj_remove_style_all(cont);
    lv_obj_set_height(cont, LV_SIZE_CONTENT);
    
    source_label = lv_label_create(cont);
    lv_obj_set_style_text_font(source_label, source_font_large, 0);
    lv_obj_set_style_text_color(source_label, lv_color_hex(0x504d6d), 0);
    lv_label_set_text(source_label, music_player_source_string_get(music_player_current_source_get()));
    lv_obj_set_height(source_label, lv_font_get_line_height(source_font_large));
    lv_obj_set_align(source_label, LV_ALIGN_CENTER);

    return cont;
}

static lv_obj_t *_create_source_img_box(lv_obj_t *parent)
{
    int i;
    lv_coord_t size = 150;
    lv_coord_t offset = 30;
    int index;
    int32_t zoom = 50;
    lv_obj_t *focus_obj;
    
    lv_obj_t *source_img_cont = lv_obj_create(parent);
    lv_obj_remove_style_all(source_img_cont);
    lv_obj_set_size(source_img_cont, lv_pct(100), LV_SIZE_CONTENT);
    lv_obj_set_flex_flow(source_img_cont, LV_FLEX_FLOW_ROW);
//    lv_obj_set_scroll_snap_x(source_img_cont, LV_SCROLL_SNAP_CENTER);

    for (i=0; i<SOURCE_MAX; i++)
    {
        lv_obj_t * cont = lv_obj_create(source_img_cont);
        lv_obj_remove_style_all(cont);
        lv_obj_set_size(cont, LV_HOR_RES/3, size + 2 * offset);

        lv_obj_t *obj = lv_obj_create(cont);
        lv_obj_set_size(obj, size, size);
        lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, 0);
        lv_obj_set_style_clip_corner(obj, true, 0);
        lv_obj_align(obj, LV_ALIGN_BOTTOM_MID, 0, 0);
        lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
        lv_group_add_obj(lv_group_get_default(), obj);
        lv_obj_add_style(obj, &source_focus_style, LV_STATE_FOCUSED);
        lv_obj_add_event_cb(obj, _source_event_cb, LV_EVENT_FOCUSED, (void *)i);
        lv_obj_add_event_cb(obj, _source_event_cb, LV_EVENT_DEFOCUSED, (void *)i);
        lv_obj_add_event_cb(obj, _source_event_cb, LV_EVENT_CLICKED, (void *)i);
        lv_obj_add_event_cb(obj, _source_event_cb, LV_EVENT_KEY, (void *)i);

        if (source_img_buff[i] != NULL)
        {
            lv_obj_t *img = lv_img_create(obj); 
            lv_img_set_src(img, source_img_buff[i]);
            lv_obj_set_align(img, LV_ALIGN_CENTER);
        }

        if (i == music_player_current_source_get())
        {
            focus_obj = obj;
        }
    }

    lv_group_focus_obj(focus_obj);

    return source_img_cont;
}

static void _source_timer_cb(lv_timer_t *timer)
{
    volumio_music_page_switch(PAGE_ID_PLAYER);
}

static void _anim_y_cb(void *val, int32_t v)
{
    lv_obj_set_style_translate_y(val, v, 0);
}

static void _anim_zoom_cb(void *val, int32_t v)
{
    if (lv_obj_get_child(val, 0) != NULL)
    {
        lv_img_set_zoom(lv_obj_get_child(val, 0), v);
    }
}

static void _focus_async_cb(void *param)
{
    lv_coord_t offset = 30;
    int32_t zoom = 50;
    focus_obj_t *p_focus = (focus_obj_t *)param;
    
    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_path_cb(&a, lv_anim_path_linear);
    lv_anim_set_time(&a, 200);
    lv_anim_set_var(&a, p_focus->obj);
    
    lv_anim_set_exec_cb(&a, _anim_y_cb);
    lv_anim_set_values(&a, 0, -offset);
    lv_anim_start(&a);
    
    lv_anim_set_exec_cb(&a, _anim_zoom_cb);
    lv_anim_set_values(&a, LV_IMG_ZOOM_NONE, LV_IMG_ZOOM_NONE + zoom);
    lv_anim_start(&a);

#if 0    
    lv_obj_scroll_to_view(lv_obj_get_parent(p_focus->obj), LV_ANIM_ON);
#else
    if (SOURCE_MAX > 3)
    {
        if ((p_focus->index>1) && (p_focus->index<SOURCE_MAX-1))
            lv_obj_scroll_to_x(lv_obj_get_parent(lv_obj_get_parent(p_focus->obj)), (p_focus->index - 1) * (LV_HOR_RES / 3), LV_ANIM_ON);
        else if (p_focus->index >= SOURCE_MAX-1)
            lv_obj_scroll_to_x(lv_obj_get_parent(lv_obj_get_parent(p_focus->obj)), (p_focus->index - 2) * (LV_HOR_RES / 3), LV_ANIM_ON);
        else 
            lv_obj_scroll_to_x(lv_obj_get_parent(lv_obj_get_parent(p_focus->obj)), 0, LV_ANIM_ON);
    }
#endif
    
    lv_label_set_text(source_label, music_player_source_string_get(p_focus->index));
    lv_timer_reset(source_timer);
}

static void _defocus_async_cb(void *param)
{
    lv_coord_t offset = 30;
    int32_t zoom = 50;
    defocus_obj_t *p_defocus = (defocus_obj_t *)param;
    
    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_path_cb(&a, lv_anim_path_linear);
    lv_anim_set_time(&a, 200);
    lv_anim_set_var(&a, p_defocus->obj);
            
    lv_anim_set_exec_cb(&a, _anim_y_cb);
    lv_anim_set_values(&a, -offset, 0);
    lv_anim_start(&a);
    
    lv_anim_set_exec_cb(&a, _anim_zoom_cb);
    lv_anim_set_values(&a, LV_IMG_ZOOM_NONE + zoom, LV_IMG_ZOOM_NONE);
    lv_anim_start(&a);
}

static void _source_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    static bool focus[SOURCE_MAX] = {0};
    
    if (code == LV_EVENT_KEY)
    {
        lv_key_t key = lv_indev_get_key(lv_indev_get_act());
        switch (key)
        {
            case LV_KEY_HOME:
            case LV_KEY_BACKSPACE:
                volumio_music_page_switch(PAGE_ID_PLAYER);
                break;
        }
    }
    else if (code == LV_EVENT_FOCUSED)
    {
        int index = (int)lv_event_get_user_data(e);
        lv_obj_t *obj = lv_event_get_current_target(e);
        
        LV_LOG_USER("focus %d", index);
        if (focus[index]==false && leave==false)
        {
            focus_obj.obj = obj;
            focus_obj.index = index;
            lv_async_call(_focus_async_cb, &focus_obj);
        }
        focus[index] = true;
    }
    else if (code == LV_EVENT_DEFOCUSED)
    {
        int index = (int)lv_event_get_user_data(e);
        lv_obj_t *obj = lv_event_get_current_target(e);
        
        LV_LOG_USER("defocus %d", index);
        if (focus[index]==true && leave==false)
        {
            defocus_obj.obj = obj;
            defocus_obj.index = index;
            lv_async_call(_defocus_async_cb, &defocus_obj);
        }
        focus[index] = false;        
    }
    else if (code == LV_EVENT_CLICKED)
    {
        int index = (int)lv_event_get_user_data(e);

        music_player_switch_source_cb(index);
        volumio_music_page_switch(PAGE_ID_PLAYER);
    }
}




